package com.cloud.note.service.impl;

import com.cloud.note.dto.attachment.AttachmentResponse;
import com.cloud.note.dto.note.NoteResponse;
import com.cloud.note.dto.tag.TagResponse;
import com.cloud.note.model.Attachment;
import com.cloud.note.model.Favorite;
import com.cloud.note.model.FavoriteId;
import com.cloud.note.model.Note;
import com.cloud.note.repository.AttachmentRepository;
import com.cloud.note.repository.FavoriteRepository;
import com.cloud.note.repository.NoteRepository;
import com.cloud.note.service.FavoriteService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class FavoriteServiceImpl implements FavoriteService {

    @Autowired
    private FavoriteRepository favoriteRepository;

    @Autowired
    private NoteRepository noteRepository;

    @Autowired
    private AttachmentRepository attachmentRepository;

    @Override
    public Page<NoteResponse> getFavorites(String userId, Pageable pageable) {
        Page<Note> notePage = favoriteRepository.findFavoriteNotes(userId, pageable);
        return notePage.map(this::convertToNoteResponse);
    }

    @Override
    @Transactional
    public void addToFavorite(String userId, String noteId) {
        // 检查笔记是否存在
        Note note = noteRepository.findByIdAndUserId(noteId, userId)
                .orElseThrow(() -> new RuntimeException("笔记不存在"));

        // 检查是否已收藏
        if (favoriteRepository.existsByUserIdAndNoteId(userId, noteId)) {
            throw new RuntimeException("笔记已收藏");
        }

        // 创建收藏
        Favorite favorite = new Favorite();
        favorite.setUserId(userId);
        favorite.setNoteId(noteId);
        favorite.setCreatedAt(LocalDateTime.now());

        favoriteRepository.save(favorite);

        // 更新笔记星标状态
        note.setStarred(true);
        noteRepository.save(note);
    }

    @Override
    @Transactional
    public void removeFromFavorite(String userId, String noteId) {
        // 检查笔记是否存在
        Note note = noteRepository.findByIdAndUserId(noteId, userId)
                .orElseThrow(() -> new RuntimeException("笔记不存在"));

        // 检查是否已收藏
        if (!favoriteRepository.existsByUserIdAndNoteId(userId, noteId)) {
            throw new RuntimeException("笔记未收藏");
        }

        // 删除收藏
        favoriteRepository.deleteByUserIdAndNoteId(userId, noteId);

        // 更新笔记星标状态
        note.setStarred(false);
        noteRepository.save(note);
    }

    @Override
    public boolean isNoteFavorited(String userId, String noteId) {
        return favoriteRepository.existsByUserIdAndNoteId(userId, noteId);
    }

    private NoteResponse convertToNoteResponse(Note note) {
        // 转换标签
        List<TagResponse> tagResponses = note.getTags().stream()
                .map(tag -> TagResponse.builder()
                        .id(tag.getId())
                        .name(tag.getName())
                        .color(tag.getColor())
                        .noteCount(null) // 这里不需要统计笔记数量
                        .createdAt(tag.getCreatedAt())
                        .build())
                .collect(Collectors.toList());

        // 获取附件
        List<Attachment> attachments = attachmentRepository.findByNoteId(note.getId());

        // 转换附件
        List<AttachmentResponse> attachmentResponses = attachments.stream()
                .map(attachment -> AttachmentResponse.builder()
                        .id(attachment.getId())
                        .name(attachment.getName())
                        .type(attachment.getType())
                        .uri(attachment.getUri())
                        .size(attachment.getSize())
                        .isSynced(attachment.isSynced())
                        .createdAt(attachment.getCreatedAt())
                        .build())
                .collect(Collectors.toList());

        return NoteResponse.builder()
                .id(note.getId())
                .title(note.getTitle())
                .content(note.getContent())
                .createdAt(note.getCreatedAt())
                .updatedAt(note.getUpdatedAt())
                .color(note.getColor())
                .isSynced(note.isSynced())
                .lastSyncedAt(note.getLastSyncedAt())
                .tags(tagResponses)
                .isStarred(note.isStarred())
                .isArchived(note.isArchived())
                .isTrashed(note.isTrashed())
                .isReminder(note.isReminder())
                .reminderDate(note.getReminderDate())
                .category(note.getCategory())
                .attachments(attachmentResponses)
                .build();
    }
}